tree grammar Evaluator;

options {
    tokenVocab=Expression;
    ASTLabelType=CommonTree;
}

@header {
package blms.util.expression;
import blms.domain.Expression.Context;
}

@members {
    /** Map variable name to Integer object holding value */
    private Context context;

    /** Set up an evaluator with a node stream; and a context */
    public Evaluator(CommonTreeNodeStream nodes, Context context) {
        this(nodes);
        this.context = context;
    }
}

eval returns [int value]
    :  expr { return $expr.value; }
    ;

expr returns [int value]
    :   ^('+' a=expr b=expr)  {$value = a+b;}
    |   ^('-' a=expr b=expr)  {$value = a-b;}   
    |   ^('*' a=expr b=expr)  {$value = a*b;}
    |   ^('/' a=expr b=expr)  {$value = a/b;}
    |   ID
        {
            String variable = $ID.text;
            Integer v = context.getVariable(variable);
            if (v != null) {
                $value = v.intValue();
            } else {
                throw new RuntimeException(blms.util.BLMSMessages.UNKNOWN_VARIABLE);
            }
        }
    |   INT    { $value = Integer.valueOf($INT.text); }
    ;